﻿namespace AsyncAndTask;

class Program
{
    // 模拟一个耗时的异步操作
    static async Task<string> DownloadDataAsync(string url)
    {
        Console.WriteLine($"开始下载：{url}");
        await Task.Delay(1000); //模拟网络延迟
        Console.WriteLine($"下载完成{url}");
        return $"从{url}开始下载数据";
    }

    // 在一个方法中使用 await 调用异步方法
    static async Task ProcessDownloadAsync(string url)
    {
        Console.WriteLine($"准备开始处理下载");
        // 当遇到 await 时，当前方法会暂停，释放线程，直到 DownloadDataAsync 完成
        string date = await DownloadDataAsync(url);
        Console.WriteLine($"处理下载的数据{date}");
    }

    // 调用入口
    static async Task RunAsync()
    {
        Console.WriteLine($"主程序开始。。");
        // 调用一个异步方法，不会阻塞主线程
        Task processDownloadAsync = ProcessDownloadAsync("https://www.baidu.com");
        Console.WriteLine($"主线程继续执行其他任务");
        // 等待异步任务完成 (在控制台应用中通常需要等待，否则程序可能提前退出)
        await processDownloadAsync;
        Console.WriteLine("主线程结束...");
    }


    // Task<TResult> 和处理异步方法的返回值及异常
    static async Task<int> CalculateSumAsync(int a, int b)
    {
        Console.WriteLine("开始计算...");
        await Task.Delay(1000); // 模拟计算耗时
        if (a < 0 || b < 0)
        {
            throw new Exception("输入不能为负数");
        }

        Console.WriteLine("计算完成");
        return a + b;
    }

    //调用并处理返回值和异常
    static async Task UseCalculateSumAsync()
    {
        try
        {
            Console.WriteLine("调用CalculateSumAsync(5,10)");
            int result = await CalculateSumAsync(5, 10);
            Console.WriteLine($"结果{result}");
            Console.WriteLine("调用 CalculateSumAsync(-1, 10)...");
            int errorResult = await CalculateSumAsync(-1, 10);
            Console.WriteLine($"这个不会被输出: {errorResult}");
        }
        catch (Exception e)
        {
            Console.WriteLine($"异常：{e.Message}");
        }
    }

    // 使用 Task.Run 将同步 CPU 密集型任务转为异步
    static async Task ProcessLargeArrayAsync(int[] data)
    {
        Console.WriteLine("开始处理大型数组");
        //将CPU密集型计算放在 Task.Run 中，避免阻塞调用线程
        int sum = await Task.Run(() =>
        {
            long total = 0;
            foreach (var item in data)
            {
                total += item;
            }

            //睡3秒钟
            Thread.Sleep(3000);
            return (int)total;
        });
        Console.WriteLine($"数组总和为{sum}");
    }

    static async Task Main(string[] args)
    {
        // await RunAsync();
        await UseCalculateSumAsync();
        await ProcessLargeArrayAsync([1, 2, 3, 4, 5]);
    }
}